part of _;

extension on MainPage_Video {
  Widget view_video() {
    return VideoPager(
      models: models,
      pageSize: 5,
      autoNext: autoNext,
      onCreate: (controller) => videoPagerController = controller,
      onLoadNextPage: () async => await controller_loadData(false),
      onItemLongPress: (model) {
        showModalBottomSheet(
          context: context,
          builder: (context) {
            return Container(
              width: yScreenSize().width,
              padding: EdgeInsets.all(10),
              decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.only(topLeft: Radius.circular(10), topRight: Radius.circular(10))),
              child: GridView(
                primary: false,
                shrinkWrap: true,
                gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 5),
                children: [
                  YButton(
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.center,
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        Icon(autoNext ? Icons.file_download_off_rounded : Icons.download_rounded),
                        YSpacer(height: 10),
                        Text(autoNext ? "取消续播" : "自动续播"),
                      ],
                    ),
                    onTap: () {
                      autoNext = !autoNext;
                      setState(() {});
                      Navigator.of(context).pop();
                    },
                  ),
                ],
              ),
            );
          },
        );
      },
    );
  }

  Widget view_publish() {
    return Positioned(
      bottom: 15,
      right: 15,
      child: YButton(
        width: 50,
        height: 50,
        borderRadius: BorderRadius.circular(99),
        decoration: BoxDecoration(color: YConfig.themeColor),
        child: Icon(Icons.add_rounded, color: Colors.white),
        onTap: () async {
          final result_select = (await AssetUtils.selectAssets(requestType: RequestType.video))?.firstOrNull;
          if (result_select == null) return;
          yShowProgress();
          final result_compress = await CompressUtils.compressVideo((await result_select.file)!.path);
          yDismissProgress();
          yShowProgress();
          YOSS.upload(
            filepaths: [result_compress],
            dir: "short_video",
            onFinish: (isSuccess, urls, error) {
              yDismissProgress();
              if (!isSuccess) {
                yToast(error!);
                return;
              }
              yPost(IFinal.Jkids.publishVideo, {
                "video": urls!.first,
              }, (isSuccess, results, code, message) {
                if (!isSuccess) return;
                yToast("视频发布成功");
              });
            },
          );
        },
      ),
    );
  }
}

class VideoPagerController {
  VideoPagerController({
    required this.state,
  });

  _VideoPagerState state;

  void pause() {
    if (state.lastChewieController != null && state.lastChewieController!.isPlaying) state.lastChewieController?.pause();
  }
}

class VideoPager extends StatefulWidget {
  VideoPager({
    required this.models,
    required this.onLoadNextPage,
    this.onCreate,
    this.autoNext = false,
    this.onItemLongPress,
    this.pageSize = 5,
    Key? key,
  }) : super(key: key);

  final List<VideoModel> models;
  final bool autoNext;
  final Function(VideoPagerController controller)? onCreate;
  final Future<List<VideoModel>> Function() onLoadNextPage;
  final Function(VideoModel model)? onItemLongPress;
  final int pageSize;

  @override
  State<StatefulWidget> createState() => _VideoPagerState();
}

class _VideoPagerState extends State<VideoPager> {
  final pageController = PageController();
  ChewieController? lastChewieController;
  VoidCallback? listener;
  int index = 0;

  @override
  void initState() {
    super.initState();
    playVideo(widget.models.firstOrNull?.video);
    widget.onCreate?.call(VideoPagerController(state: this));
  }

  @override
  void dispose() {
    pageController.dispose();
    lastChewieController?.dispose();
    super.dispose();
  }

  Future<void> playVideo(String? video) async {
    if (video == null) return;
    if (listener != null) lastChewieController?.videoPlayerController.removeListener(listener!);
    lastChewieController?.pause();
    await lastChewieController?.videoPlayerController.dispose();
    lastChewieController?.dispose();
    setState(() {});

    String cacheKey() => "video_cache_$video";
    late VideoPlayerController videoPlayerController;
    final path = await yRead(cacheKey());
    if (path != null && File(path).existsSync()) {
      videoPlayerController = VideoPlayerController.file(File(path));
    } else {
      videoPlayerController = VideoPlayerController.network(video);
      final path = "${await FileUtils.getDir(FileDir.cache_video)}${DateTime.now().microsecondsSinceEpoch}_${FileUtils.getFileName(video)}";
      final cancelToken = CancelToken();
      Dio().download(video, path, cancelToken: cancelToken, deleteOnError: true, onReceiveProgress: (count, total) {
        if (total > 100 * 1024 * 1024) {
          // 100MB以上的文件不缓存，此处停止下载
          cancelToken.cancel();
          return;
        }
      }).then((response) {
        if (response.statusCode != 200) return;
        ySave(cacheKey(), path);
      });
    }
    videoPlayerController = videoPlayerController
      ..initialize().then((value) {
        setState(() {});
        videoPlayerController.play();
      });
    lastChewieController = ChewieController(
      videoPlayerController: videoPlayerController,
      autoInitialize: false,
      autoPlay: false,
      showControls: false,
      showControlsOnInitialize: false,
      looping: false,
      errorBuilder: (context, errorMessage) => Center(child: Icon(Icons.error_outline, color: Colors.white, size: 50)),
    );
    listener = () {
      if (lastChewieController!.videoPlayerController.value.position >= lastChewieController!.videoPlayerController.value.duration) {
        if (widget.autoNext) {
          pageController.nextPage(duration: Duration(milliseconds: 500), curve: Curves.linearToEaseOut);
        } else {
          lastChewieController!.play();
        }
      }
    };
    lastChewieController?.videoPlayerController.addListener(listener!);
  }

  Widget view_video(int index) {
    if (this.index != index) return YEmpty();
    if (lastChewieController == null) return YEmpty();
    if (!(lastChewieController?.videoPlayerController.value.isInitialized ?? false)) return YEmpty();
    return GestureDetector(
      child: Stack(
        alignment: Alignment.center,
        children: [
          Chewie(controller: lastChewieController!),
          lastChewieController!.isPlaying ? YEmpty() : Icon(Icons.play_arrow_rounded, color: Colors.white.withAlpha(200), size: 100),
        ],
      ),
      onTap: () {
        lastChewieController?.togglePause();
        setState(() {});
      },
    );
  }

  Widget view_image(int index) {
    final model = widget.models[index];
    if (model.image.isEmpty) return YEmpty();
    if (lastChewieController?.videoPlayerController.value.isInitialized ?? false) return YEmpty();
    return ImageFiltered(
      imageFilter: ImageFilter.blur(sigmaX: 20, sigmaY: 20),
      child: YImage(yScreenSize().width, yScreenSize().height, model.image, fit: BoxFit.cover),
    );
  }

  Widget view_loading(int index) {
    final model = widget.models[index];
    if (lastChewieController?.videoPlayerController.value.isInitialized ?? false) return YEmpty();
    return MyLoader();
  }

  @override
  Widget build(BuildContext context) {
    return PageView.builder(
      scrollDirection: Axis.vertical,
      onPageChanged: (value) async {
        index = value;
        if (value >= widget.models.length - 2) {
          widget.models.addAll(await widget.onLoadNextPage());
          setState(() {});
        }
        playVideo(widget.models[value].video);
      },
      allowImplicitScrolling: true,
      controller: pageController,
      itemCount: widget.models.length,
      itemBuilder: (context, index) {
        return GestureDetector(
          child: Stack(
            fit: StackFit.expand,
            alignment: Alignment.center,
            children: [
              YAnimatedSwitcher(child: view_video(index)),
              // YAnimatedSwitcher(child: view_image(index)),
              YAnimatedSwitcher(child: view_loading(index)),
            ],
          ),
          onLongPress: () => widget.onItemLongPress?.call(widget.models[index]),
        );
      },
    );
  }
}
